package com.sto.stoapp.manager;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Handler;
import android.util.Log;

import com.sto.stoapp.activity.R;
import com.sto.stoapp.db.StoFilePreference;
import com.sto.stoapp.log.ExceptionLog;
import com.sto.stoapp.util.Helper;

/**
 * 蓝牙通信管理类
 *
 * @author hb
 *
 */
public class BlueWeigthManager {
	// 更新蓝牙数据
	public static final int UPDATE_BLUE_DATA = 0xfe;
	// 读取数据失败
	public static final String READ_ERROR = "read_error";
	// 连接失败
	public static final String CONNECT_FAIL = "connect_fail";
	// 没有选秤的型号
	public static final String NO_SELECT_SCALE_MODEL = "no_select_Scale Model";

	private BluetoothAdapter mBTAdapter;

	private BluetoothDevice mBTDevice;

	public BluetoothSocket mBTSocket;

	private Handler blueHandler;

	private ConnectThread connectThread;

	private Context context;
	// 蓝牙mac地址
	private String machineCode;
	// 秤类型
	public String scalesType;
	// 小数点位数
	public String decimalPlaces;

	// 蓝牙连接状态
	public Boolean isconnect = false;

	// 获取蓝牙连接状态 true 表示连接，false 没有连接
	public Boolean getIsconnect() {
		return isconnect;
	}

	// 设置蓝牙连接状态 true 表示连接，false 没有连接
	public void setIsconnect(Boolean isconnect) {
		this.isconnect = isconnect;
	}

	/**
	 * 蓝牙操作界面
	 *
	 * @param blueHandler
	 *            数据接收handler
	 * @param machineCode
	 *            蓝牙mac地址
	 * @param scalesType
	 *            秤类型
	 */
	public BlueWeigthManager(Context context, Handler blueHandler,
							 String machineCode) {

		this.blueHandler = blueHandler;
		this.machineCode = machineCode;
		this.context = context;
		mBTAdapter = BluetoothAdapter.getDefaultAdapter();
		scalesType = StoFilePreference.getInstance(context)
				.getSelectedScalesControl();
		decimalPlaces = StoFilePreference.getInstance(context)
				.getSelectedDecimalPlacesControl();
	}

	/**
	 * 连接具体某个max地址的蓝牙设备
	 */
	public synchronized void connect() {
		connectThread = new ConnectThread();
		connectThread.start();
	}

	/**
	 * 设备蓝牙是否开启
	 *
	 * @return ture 已开启;false 未开启
	 */
	public boolean bluetoothIsEnabled() {
		if (mBTAdapter.isEnabled())
			return true;
		return false;
	}

	/**
	 * 判断当前mac地址是否已经匹配过
	 *
	 * @param macAddress
	 *            待验证的MAC地址
	 * @return ture:已匹配过;false:未匹配过
	 */
	public boolean isBonded(String macAddress) {
		boolean isTrue = false;
		List<BluetoothDevice> devices = getBondedDevice();
		for (BluetoothDevice device : devices) {
			if (device.getAddress().equals(macAddress)) {
				isTrue = true;
				break;
			}
		}
		return isTrue;
	}

	/**
	 * 得到已绑定的蓝牙设备
	 *
	 * @return
	 */
	public List<BluetoothDevice> getBondedDevice() {
		Set<BluetoothDevice> devices = mBTAdapter.getBondedDevices();
		List<BluetoothDevice> list = new ArrayList<BluetoothDevice>();
		if (devices != null && devices.size() > 0) {
			for (Iterator<BluetoothDevice> iterator = devices.iterator(); iterator
					.hasNext();) {
				BluetoothDevice bluetoothDevice = iterator.next();
				list.add(bluetoothDevice);
			}
		}
		return list;
	}

	/**
	 * 取消连接
	 */
	public synchronized void cancelConnect() {
		try {
			Log.i("BlueWeigthManager", "ConnectThread cancelConnect start");
			if (connectThread != null) {
				connectThread.setEnRead(false);
			}

			if (mBTSocket != null) {
				if (mBTSocket.getInputStream() != null) {
					mBTSocket.getInputStream().close();
				}
			}

			if (mBTSocket != null) {
				Log.i("BlueWeigthManager", "ConnectThread mBTSocket.close();");
				mBTSocket.close();
				mBTSocket = null;
			}
			System.gc();
			setIsconnect(false);
			Log.i("BlueWeigthManager", "ConnectThread end;");
		} catch (IOException e) {
			ExceptionLog.writeLog("BlueWeigthManager",
					Helper.saveCrashInfo2File(e));
			Log.i("JBlueCancleConnect IO", e.getMessage());
			e.printStackTrace();
		}

	}

	/**
	 * 连接蓝牙线程并获取数据
	 *
	 * @author Administrator
	 *
	 */
	class ConnectThread extends Thread {

		private boolean enRead = true;
		private byte[] TDI300 = { 0x41, 0x54, 0x56, 0x31, 0x51, 0x30, 0x0d,
				0x02, 0x41, 0x44, 0x00, 0x05, 0x03 };
		private byte[] A1 = { 0x02, 0x41, 0x44, 0x30, 0x35, 0x03 };

		public ConnectThread() {

		}

		@SuppressLint("NewApi")
		@Override
		public void run() {
			super.run();

			try {
				// Method m =
				// mBTDevice.getClass().getMethod("createRfcommSocket",
				// new Class[] { int.class });
				//
				// mBTSocket = (BluetoothSocket) m.invoke(mBTDevice, 1);

				try {
					Log.i("BlueWeigthManager", "ConnectThread run");
					mBTDevice = mBTAdapter.getRemoteDevice(machineCode);
					mBTSocket = mBTDevice
							.createRfcommSocketToServiceRecord(UUID
									.fromString("00001101-0000-1000-8000-00805F9B34FB"));
					mBTAdapter.cancelDiscovery();
					Log.i("BlueWeigthManager", "ConnectThread connect");
					mBTSocket.connect();
					Log.i("BlueWeigthManager",
							"ConnectThread connected mBTSocket=" + mBTSocket);
					isconnect = true;
				} catch (Exception e) {
					isconnect = false;
					Log.i("BlueWeigthManager",
							"ConnectThread Exception=" + e.toString());
					ExceptionLog.writeLog("BlueWeigthManager",
							Helper.saveCrashInfo2File(e));

					mBTSocket.close();

					Thread.sleep(2000);
					blueHandler.obtainMessage(UPDATE_BLUE_DATA, CONNECT_FAIL)
							.sendToTarget();
					e.printStackTrace();
					return;
				}
				setIsconnect(true);
				float getData = 0;

				blueHandler
						.obtainMessage(UPDATE_BLUE_DATA, dealWeight(getData))
						.sendToTarget();
				while (enRead) {
					if (mBTSocket != null && mBTSocket.getInputStream() != null) {

						if (scalesType.equals(context
								.getString(R.string.K3190A1_type))) {
							getData = getK3190A1TypeWeight(mBTSocket);
						} else if (scalesType.equals(context
								.getString(R.string.K3190AX_type))) {
							getData = getK3190A1AndTypeWeight(mBTSocket);
						} else if (scalesType.equals(context
								.getString(R.string.K9190A1_add_type))) {
							getData = getK3190A1AndTypeWeight(mBTSocket);
						} else if (scalesType.equals(context
								.getString(R.string.K3190A7_type))) {
							getData = getK3190A7TypeWeight(mBTSocket);
						}
						else if (scalesType.equals(context
								.getString(R.string.equal_type))) {
							getData = getEqualTypeWeight(mBTSocket);
						}else if (scalesType.equals(context
								.getString(R.string.K3190A12_type))) {
							getData = getK3190A12TypeWeight(mBTSocket);
						} else if (scalesType.equals(context
								.getString(R.string.TDI300_type))) {
							getData = getK3190A1TypeWeight(mBTSocket);
						} else if (scalesType.equals(context
								.getString(R.string.TDI200A1_type))) {
							getData = getK3190A1TypeWeight(mBTSocket);
						} else if (scalesType.equals(context
								.getString(R.string.sh_qh_company))) {
							getData = getK3190A7TypeWeight(mBTSocket);
						} else {
							connectThread.setEnRead(false);
							blueHandler.obtainMessage(UPDATE_BLUE_DATA,
									NO_SELECT_SCALE_MODEL).sendToTarget();
							return;
						}
						if (getData != -100) {
							blueHandler.obtainMessage(UPDATE_BLUE_DATA,
									dealWeight(getData)).sendToTarget();

							// errorCount = 0;
						}
					}
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {

						e.printStackTrace();
					}
				}

			} catch (Exception e) {
				ExceptionLog.writeLog("BlueWeigthManager",
						Helper.saveCrashInfo2File(e));
			}
		}

		public boolean isEnRead() {
			return enRead;
		}

		public void setEnRead(boolean enRead) {
			this.enRead = enRead;
		}

		private byte[] rece = new byte[7 * 1024];
		private float retData = -100;
		private int offset = 0, len = 0;
		private int MAX = rece.length - 1;

		/**
		 * 获取K3190A7数据并解析
		 *
		 * @return
		 * @throws IOException
		 */
		private float getK3190A7TypeWeight(BluetoothSocket mBTSocket) {
			retData = -100;
			offset = 0;
			len = 0;
			try {
				Thread.sleep(70);

				while (enRead) {

					len = mBTSocket.getInputStream().read(rece, offset,
							MAX - offset);
					offset += len;
					if (offset > 0) {
						String data = new String(rece, 0, offset, "utf-8");
						String[] str = data.split("=");
						if (str.length < 2)
							return retData;
						if (str[1].length() > 5) {
							StringBuffer sb = new StringBuffer(str[1]);
							retData = Float.valueOf(sb.reverse().toString());
							break;
						} else if (str[0].length() > 5) {
							StringBuffer sb = new StringBuffer(str[0]);
							retData = Float.valueOf(sb.reverse().toString());
							break;
						}
					}
					if (retData != 100 || len < 0 || offset > 20) {
						break;
					}
				}
			} catch (Exception e) {
				blueHandler.obtainMessage(UPDATE_BLUE_DATA, READ_ERROR)
						.sendToTarget();
				e.printStackTrace();
				ExceptionLog.writeLog("BlueWeigthManager",
						Helper.saveCrashInfo2File(e));
			}

			return retData;
		}
		/**
		 * 获取K3190A7数据并解析
		 *
		 * @return
		 * @throws IOException
		 */
		private float getEqualTypeWeight(BluetoothSocket mBTSocket) {
			retData = -100;
			offset = 0;
			len = 0;
			try {
				Thread.sleep(70);

				while (enRead) {

					len = mBTSocket.getInputStream().read(rece, offset,
							MAX - offset);
					offset += len;
					if (offset > 0) {
						String data = new String(rece, 0, offset, "utf-8");
						String[] str = data.split("==");
						if (str.length < 2)
							return retData;
						if (str[1].length() > 5) {
							StringBuffer sb = new StringBuffer(str[1]);
							retData = Float.valueOf(sb.reverse().toString());
							break;
						} else if (str[0].length() > 5) {
							StringBuffer sb = new StringBuffer(str[0]);
							retData = Float.valueOf(sb.reverse().toString());
							break;
						}
					}
					if (retData != 100 || len < 0 || offset > 20) {
						break;
					}
				}
			} catch (Exception e) {
				blueHandler.obtainMessage(UPDATE_BLUE_DATA, READ_ERROR)
						.sendToTarget();
				e.printStackTrace();
				ExceptionLog.writeLog("BlueWeigthManager",
						Helper.saveCrashInfo2File(e));
			}

			return retData;
		}
		/**
		 * 获取K3190A1+数据并解析
		 *
		 * @param mBTSocket
		 * @return
		 * @throws IOException
		 */
		private float getK3190A1AndTypeWeight(BluetoothSocket mBTSocket) {
			retData = -100;
			offset = 0;
			len = 0;

			try {
				Thread.sleep(70);
				while (enRead) {
					mBTSocket.getOutputStream().write(A1);
					mBTSocket.getOutputStream().flush();
					len = mBTSocket.getInputStream().read(rece, offset,
							MAX - offset);
					offset += len;

					if (offset > 0) {
						String data = new String(rece, 0, offset, "utf-8");
						String[] str = data.split("AD\\+");
						if (str.length < 2)
							return retData;
						// 取协议的中间值 AD+00034021B
						if (str[1].length() > 6) {
							float it = Float.valueOf(str[1].substring(0, 6));
							char ch = str[1].charAt(6);
							retData = it / mypow(10, Character.digit(ch, 10));
						}
					}
					if (len < 0 || offset > 20) {
						break;
					}
				}

			} catch (Exception e) {
				blueHandler.obtainMessage(UPDATE_BLUE_DATA, READ_ERROR)
						.sendToTarget();
				e.printStackTrace();
				ExceptionLog.writeLog("BlueWeigthManager",
						Helper.saveCrashInfo2File(e));
			}

			return retData;
		}

		/**
		 * 获取TDI300/200数据并解析
		 *
		 * @param mBTSocket
		 * @return
		 * @throws IOException
		 */
		private float getK3190A1TypeWeight(BluetoothSocket mBTSocket) {
			retData = -100;
			offset = 0;
			len = 0;

			try {
				Thread.sleep(100);
				while (enRead) {
					mBTSocket.getOutputStream().write(TDI300);
					mBTSocket.getOutputStream().flush();
					len = mBTSocket.getInputStream().read(rece, offset,
							MAX - offset);
					offset += len;

					if (offset > 0) {
						String data = new String(rece, 0, offset, "utf-8");
						String[] str = data.split("AD");
						if (str.length < 2)
							return retData;
						// 取协议的中间值 AD+12345661AD+22222222AD+42654895
						if (str[1].length() > 6) {
							float it = Float.valueOf(str[1].substring(1, 7));
							// char ch = str[1].charAt(7);
							retData = it / 1000;
						}
					}
					if (len < 0 || offset > 20) {
						break;
					}
				}

			} catch (Exception e) {
				blueHandler.obtainMessage(UPDATE_BLUE_DATA, READ_ERROR)
						.sendToTarget();
				e.printStackTrace();
				ExceptionLog.writeLog("BlueWeigthManager",
						Helper.saveCrashInfo2File(e));
			}

			return retData;
		}

		/**
		 * 获取K3190A12数据并解析
		 *
		 * @return
		 * @throws IOException
		 */
		private float getK3190A12TypeWeight(BluetoothSocket mBTSocket) {
			retData = -100;
			offset = 0;
			len = 0;

			try {
				Thread.sleep(70);
				while (enRead) {

					mBTSocket.getOutputStream().write('R');
					mBTSocket.getOutputStream().flush();
					len = mBTSocket.getInputStream().read(rece, offset,
							MAX - offset);
					offset += len;

					if (offset > 0) {
						String data = new String(rece, 0, offset, "utf-8");
						String[] str = data.split("=");
						if (str.length < 2)
							return retData;

						// 取协议的中间值 =07.0000=07.
						if (str[1].length() > 5) {
							StringBuffer sb = new StringBuffer(str[1]);
							retData = Float.valueOf(sb.reverse().toString());
							break;
						} else if (str[0].length() > 5) {
							StringBuffer sb = new StringBuffer(str[0]);
							retData = Float.valueOf(sb.reverse().toString());
							break;
						}
					}
					if (len < 0 || offset > 20) {
						break;
					}
				}

			} catch (Exception e) {
				blueHandler.obtainMessage(UPDATE_BLUE_DATA, READ_ERROR)
						.sendToTarget();
				e.printStackTrace();
				ExceptionLog.writeLog("BlueWeigthManager",
						Helper.saveCrashInfo2File(e));
			}

			return retData;
		}

		// 精确小数位
		private String dealWeight(float weight) {
			String retWeight = "0.0", weightStr = "0.0";
			try {
				weightStr = String.valueOf(weight);
				String str[] = weightStr.split("\\.");
				if (str.length > 1) {
					// 小数点一位
					if (decimalPlaces.equals(context
							.getString(R.string.decimal_places_one))) {
						if (str[1].length() >= 2) {
							str[1] = str[1].substring(0, 1);
						}
					}
					// 小数点二位
					else if (decimalPlaces.equals(context
							.getString(R.string.decimal_places_two))) {
						if (str[1].length() >= 3) {
							str[1] = str[1].substring(0, 2);
						}
					}
					// 小数点三位
					else if (decimalPlaces.equals(context
							.getString(R.string.decimal_places_three))) {
						if (str[1].length() >= 4) {
							str[1] = str[1].substring(0, 3);
						}
					}
				} else {
					return weightStr;
				}
				retWeight = str[0] + "." + str[1];
			} catch (Exception e) {
				e.printStackTrace();
				ExceptionLog.writeLog("BlueWeigthManager",
						Helper.saveCrashInfo2File(e));
			}
			return retWeight;
		}

		private float mypow(int x, int y) {
			float ret = 1;
			while (y > 0) {
				ret *= x;
				y--;
			}
			return ret;
		}
	}

	/******************** 以下为动态称测试 **********************/
	/**
	 * 连接具体某个max地址的蓝牙设备
	 *
	 * @param preOrNext
	 *            扫描在前还是后
	 * @return BluetoothSocket
	 */
	public BluetoothSocket connectBearing() {
		try {
			mBTAdapter = BluetoothAdapter.getDefaultAdapter();
			mBTDevice = mBTAdapter.getRemoteDevice(StoFilePreference
					.getInstance(context).getBluetoothMacAddress());

			mBTSocket = mBTDevice.createRfcommSocketToServiceRecord(UUID
					.fromString("00001101-0000-1000-8000-00805F9B34FB"));

			mBTSocket.connect();
		} catch (IOException connectException) {
			connectException.printStackTrace();
			ExceptionLog.writeLog("BlueWeigthManager connectBearing",
					connectException.getMessage());
			return null;
		}
		return mBTSocket;

	}
}
